package com.ruoyi.eqmonitor.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.SpringUtils;
import com.ruoyi.eqmonitor.dispose.dtos.OpentsdbTagsData;
import com.ruoyi.eqmonitor.dispose.service.IotService;
import com.ruoyi.eqmonitor.domain.OptDevice;
import com.ruoyi.eqmonitor.domain.OptDeviceMonitorAnalyseData;
import com.ruoyi.eqmonitor.domain.OptDeviceMonitorLastData;
import com.ruoyi.eqmonitor.dtos.OptDeviceDto;
import com.ruoyi.eqmonitor.mapper.OptDeviceMonitorAnalyseDataMapper;
import com.ruoyi.eqmonitor.service.IOptDeviceMonitorAnalyseDataService;
import com.ruoyi.eqmonitor.service.IOptDeviceMonitorConfigService;
import com.ruoyi.eqmonitor.service.IOptDeviceMonitorLastDataService;
import com.ruoyi.eqmonitor.service.IOptDeviceService;
import com.ruoyi.eqmonitor.utils.Constant;
import com.ruoyi.eqmonitor.utils.OpenTSDBUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.nio.reactor.IOReactorException;
import org.opentsdb.client.OpenTSDBClient;
import org.opentsdb.client.bean.request.SubQuery;
import org.opentsdb.client.bean.response.QueryResult;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.Future;
import java.util.stream.Collectors;


/**
 * 设备监测最新实时数据Service业务层处理
 *
 * @author ruoyi
 * @date 2022-11-25
 */
@Slf4j
@Service
public class OptDeviceAnalyseLastDataServiceImpl extends ServiceImpl<OptDeviceMonitorAnalyseDataMapper, OptDeviceMonitorAnalyseData> implements IOptDeviceMonitorAnalyseDataService {

    @Resource
    private OpenTSDBUtils openTSDBUtils;

    @Resource
    private IOptDeviceService iOptDeviceService;

    @Resource
    private IOptDeviceMonitorLastDataService deviceMonitorLastDataService;

    @Resource
    private IOptDeviceMonitorConfigService monitorConfigService;

    @Override
    public List<OptDeviceMonitorAnalyseData> selectLastDataByDeviceCode(String deviceCode) {
        return baseMapper.selectLastDataByDeviceCode(deviceCode);
    }

    @Override
    public List<OptDeviceMonitorAnalyseData> selectLastDataList() {
        return baseMapper.selectLastDataList();
    }

    /**
     * 处理日累计内容
     */
    @Override
//    @Async
//    public Future<Boolean> analyseDailyAccumulation(Date today, boolean needAlarm) {
    public void analyseDailyAccumulation(Date today, boolean needAlarm) {
        long start = System.currentTimeMillis();
        log.info("{} 统计分析开始", today);
        DateTime startTime = DateUtil.beginOfDay(DateUtil.offsetDay(today, -1));
        DateTime endTime = DateUtil.endOfDay(DateUtil.offsetDay(today, -1));
//        // 先统计日累计流量
//        Future<Boolean> r1 = self.analyseCumulativeDischarge(startTime, endTime);
//        // 再查出24小时雨量最大值
//        Future<Boolean> r2 = self.analyse24HourRain(startTime, endTime);
//        // 再统计其他: [COD日均值, 氨氮日均值, 电导率日均值, 液位高度日均值 ]
//        Future<Boolean> r3 = self.analyseAvgOther(startTime, endTime, Constant.MonitorInfo.C_CC0002);
//        Future<Boolean> r4 = self.analyseAvgOther(startTime, endTime, Constant.MonitorInfo.C_CC0003);
//        Future<Boolean> r5 = self.analyseAvgOther(startTime, endTime, Constant.MonitorInfo.C_CC0006);
//        Future<Boolean> r6 = self.analyseAvgOther(startTime, endTime, Constant.MonitorInfo.C_CC0007);
//        while (true) {//死循环，每隔2000ms执行一次，判断一下这三个异步调用的方法是否全都执行完了。
//            if (r1.isDone() && r2.isDone() && r3.isDone() && r4.isDone() && r5.isDone() && r6.isDone()) {
//                break;
//            }
//            try {
//                Thread.sleep(2000);//每隔2000毫秒判断一次
//            } catch (InterruptedException e) {
//                log.error("等待聚合结束延时失败", e);
//                break;
//            }
//        }
        // 先统计日累计流量
        analyseCumulativeDischarge(startTime, endTime);
        // 再查出24小时雨量最大值
        analyse24HourRain(startTime, endTime);
        // 再统计其他: [COD日均值, 氨氮日均值, 电导率日均值, 液位高度日均值 ]
        analyseAvgOther(startTime, endTime, Constant.MonitorInfo.C_CC0002);
        analyseAvgOther(startTime, endTime, Constant.MonitorInfo.C_CC0003);
        analyseAvgOther(startTime, endTime, Constant.MonitorInfo.C_CC0006);
        analyseAvgOther(startTime, endTime, Constant.MonitorInfo.C_CC0007);
        // 最后算日均 COD日排放, 氨氮日排放
        analyseRiJun(today);

        // 判断是否是今天, 如果是今天则需要刷库
        if (DateUtil.isSameDay(today, DateUtil.date())) {
            // 将所有最新一条分析数据录入最新数据表
            List<OptDeviceMonitorLastData> lastMonitorData = flushLastMonitorData();

            // 阈值校验
            if (needAlarm) {
                validateAlarmConfig(lastMonitorData);
            }
        }

        log.info("{} 统计分析结束, 耗时: {}", today, (System.currentTimeMillis() - start));
//        return new AsyncResult<>(true);
    }


    /**
     * 阈值校验
     */
    public void validateAlarmConfig(List<OptDeviceMonitorLastData> lastMonitorData) {
        for (OptDeviceMonitorLastData lastMonitor : lastMonitorData) {
            OptDeviceDto device = iOptDeviceService.getDeviceByCode(lastMonitor.getDeviceCode());
            monitorConfigService.validateConfigAndDoAlarm(device, lastMonitor);
        }
    }

    /**
     * 将所有最新的分析数据刷新到设备最新一条数据表中
     */
    @Override
    public List<OptDeviceMonitorLastData> flushLastMonitorData() {
        // 将所有设备最新的分析数据
        List<OptDeviceMonitorAnalyseData> analyseDataList = selectLastDataList();
        // 放弃日累计雨量 -- 这个只是查询曲线使用的
        analyseDataList = analyseDataList.stream().filter(monitorLastData -> {
            return !Constant.MonitorInfo.C_CC0008.getCode().equals(monitorLastData.getCode());
        }).collect(Collectors.toList());

        // 循环每条数据 落库
        List<OptDeviceMonitorLastData> collections = new ArrayList<>();
        for (OptDeviceMonitorAnalyseData analyseData : analyseDataList) {
            OptDeviceMonitorLastData optDeviceMonitorLastData = new OptDeviceMonitorLastData();
            optDeviceMonitorLastData.setDeviceName(analyseData.getDeviceName());
            optDeviceMonitorLastData.setDeviceCode(analyseData.getDeviceCode());
            optDeviceMonitorLastData.setSiteName(analyseData.getSiteName());
            optDeviceMonitorLastData.setDeviceType(analyseData.getDeviceType());
            optDeviceMonitorLastData.setInstallTime(analyseData.getInstallTime());
            optDeviceMonitorLastData.setAbx(analyseData.getAbx());
            optDeviceMonitorLastData.setAby(analyseData.getAby());
            optDeviceMonitorLastData.setCode(analyseData.getCode());
            optDeviceMonitorLastData.setCodeValue(analyseData.getCodeValue());
            optDeviceMonitorLastData.setDataUnit(analyseData.getDataUnit());
            optDeviceMonitorLastData.setMonitorTime(analyseData.getMonitorTime());
            optDeviceMonitorLastData.setMonitorName(analyseData.getMonitorName());
            collections.add(optDeviceMonitorLastData);
        }
        deviceMonitorLastDataService.saveOrUpdateMonitorLastData(collections);
        return collections;
    }
    @Resource
    private IotService iotService;
    /**
     * 日累计流量
     * @param startTime 开始时间
     * @param endTime 结束时间
     */
    @Async
    public Future<Boolean> analyseCumulativeDischarge(Date startTime, Date endTime) {
        // 创建连接
        try {
            long start = System.currentTimeMillis();
            log.info("开始统计{} ~ {}: 日累计流量", startTime, endTime);
            Constant.MonitorInfo monitorInfo = Constant.MonitorInfo.C_CC0001;
            Constant.MonitorInfo targetMonitorInfo = getTargetMonitorInfo(monitorInfo);
            Set<String> filterEquipmentType = Arrays.stream(Constant.EquipmentTypeMonitorInfo.values())
                    .filter(item -> ListUtil.of(item.getMonitorInfos()).contains(monitorInfo))
                    .map(Constant.EquipmentTypeMonitorInfo::getTypeCode)
                    .collect(Collectors.toSet());
            if (CollectionUtil.isEmpty(filterEquipmentType)) {
                log.error("{} ~ {}: 没有设备类型含有 {} 监测指标", startTime, endTime, monitorInfo.getCode());
            }
            // 获取所有管道流量监测仪
            List<OptDevice> list = iOptDeviceService.list(Wrappers.<OptDevice>lambdaQuery().in(OptDevice::getDeviceType, filterEquipmentType));
            log.info("{} ~ {}: 日累计流量设备数量: {}", startTime, endTime, list.size());
            List<OptDeviceMonitorAnalyseData> saveList = new ArrayList<>();

            list.parallelStream().forEach(optDevice -> {
                try {
                    LocalDateTime s = LocalDateTime.ofInstant(startTime.toInstant(), ZoneId.systemDefault());
                    LocalDateTime e = LocalDateTime.ofInstant(endTime.toInstant(), ZoneId.systemDefault());
                    Double sum = iotService.maxBySnAndCode(optDevice.getDeviceCode(), targetMonitorInfo.getCode(), s, e);
                    Double sumYesterday = iotService.maxBySnAndCode(optDevice.getDeviceCode(), targetMonitorInfo.getCode(), s.minusDays(1), e.minusDays(1));
                    if (sum==null || sumYesterday==null) {
                        log.warn("{} ~ {}: 设备:{}, 日累计流量查询失败", startTime, endTime, optDevice.getDeviceCode());
                        return;
                    }

                    double value = NumberUtil.round(sum, 3).doubleValue();
                    double valueYesterday = NumberUtil.round(sumYesterday, 3).doubleValue();
                    if (value < 0) {
                        value = 0;
                    }
                    saveList.add(createAnalyseData(optDevice, monitorInfo, value-valueYesterday, startTime));
                } catch (Exception e) {
                    log.error("{} ~ {}: 设备:{}, 日累计流量查询失败", startTime, endTime, optDevice.getDeviceCode(), e);
                }
            });
            if (CollectionUtil.isNotEmpty(saveList)) {
                saveBatch(saveList);
            }
            log.info("{} ~ {}: 日累计流量统计结束, 耗时:{}", startTime, endTime, (System.currentTimeMillis() - start));
        } catch (Exception e) {
            log.error("{} ~ {}: 日累计流量查询, 失败", startTime, endTime, e);
        }
        return new AsyncResult<>(true);
    }

    /**
     * 24小时雨量
     * @param startTime 开始时间
     * @param endTime 结束时间
     */
    @Override
    @Async
    public Future<Boolean> analyse24HourRain(Date startTime, Date endTime) {
        // 创建连接
        OpenTSDBClient queryClient = null;
        try {
            long start = System.currentTimeMillis();
            log.info("开始统计{} ~ {}: 日累计雨量", startTime, endTime);

            Constant.MonitorInfo monitorInfo = Constant.MonitorInfo.C_CC0008;
            Constant.MonitorInfo targetMonitorInfo = getTargetMonitorInfo(monitorInfo);
            Set<String> filterEquipmentType = Arrays.stream(Constant.EquipmentTypeMonitorInfo.values())
                    .filter(item -> ListUtil.of(item.getMonitorInfos()).contains(monitorInfo))
                    .map(Constant.EquipmentTypeMonitorInfo::getTypeCode)
                    .collect(Collectors.toSet());
            if (CollectionUtil.isEmpty(filterEquipmentType)) {
                log.error("{} ~ {}: 没有设备类型含有 {} 监测指标", startTime, endTime, monitorInfo.getCode());
                return new AsyncResult<>(true);
            }
            // 获取所有管道流量监测仪
            List<OptDevice> list = iOptDeviceService.list(Wrappers.<OptDevice>lambdaQuery().in(OptDevice::getDeviceType, filterEquipmentType));
            log.info("日累计雨量设备数量: {}", list.size());
            List<OptDeviceMonitorAnalyseData> saveList = new ArrayList<>();
            list.parallelStream().forEach(optDevice -> {
                try {
                    Double sum = iotService.sumBySnAndCode(optDevice.getDeviceCode(), targetMonitorInfo.getCode(), startTime, endTime);

                    if (sum==null) {
                        log.warn("{} ~ {}: 设备:{}, 日累计流量查询失败", startTime, endTime, optDevice.getDeviceCode());
                        return;
                    }

                    double value = NumberUtil.round(sum, 3).doubleValue();
                    if (value < 0) {
                        value = 0;
                    }
                    saveList.add(createAnalyseData(optDevice, monitorInfo, value, startTime));
                } catch (Exception e) {
                    log.error("{} ~ {}: 设备:{}, 日累计流量查询失败", startTime, endTime, optDevice.getDeviceCode(), e);
                }
            });
            if (CollectionUtil.isNotEmpty(saveList)) {
                saveBatch(saveList);
            }
            log.info("{} ~ {}: 日累计雨量统计结束, 耗时:{}", startTime, endTime, (System.currentTimeMillis() - start));
        } catch (Exception e) {
            log.error("{} ~ {}: 日累计雨量查询, 创建opentsdb连接失败", startTime, endTime, e);
        }
        return new AsyncResult<>(true);
    }

    /**
     * 日均值 氨氮 COD等
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @param monitorInfo 统计指标
     */
    @Async
    public Future<Boolean> analyseAvgOther(Date startTime, Date endTime, Constant.MonitorInfo monitorInfo) {
        long start = System.currentTimeMillis();
        Set<String> filterEquipmentType = Arrays.stream(Constant.EquipmentTypeMonitorInfo.values())
                .filter(item -> ListUtil.of(item.getMonitorInfos()).contains(monitorInfo))
                .map(Constant.EquipmentTypeMonitorInfo::getTypeCode)
                .collect(Collectors.toSet());
        Constant.MonitorInfo targetMonitorInfo = getTargetMonitorInfo(monitorInfo);
        log.info("开始统计{} ~ {}: {}聚合内容", startTime, endTime, monitorInfo.getName());
        if (CollectionUtil.isEmpty(filterEquipmentType)) {
            log.error("{} ~ {}: 没有设备类型含有 {} 监测指标", startTime, endTime, monitorInfo.getCode());
            return new AsyncResult<>(true);
        } else if (targetMonitorInfo == null) {
            log.error("{} ~ {}: 监测指标 {} 暂无原始的分析指标", startTime, endTime, monitorInfo.getCode());
            return new AsyncResult<>(true);
        }
        // 获取所有含有这个指标的设备
        List<OptDevice> deviceList = iOptDeviceService.list(Wrappers.<OptDevice>lambdaQuery().in(OptDevice::getDeviceType, filterEquipmentType));
        log.info("{}设备数量: {}", monitorInfo.getName(), deviceList.size());
        // 20个设备为一组进行查询
        List<List<OptDevice>> splitList = ListUtil.split(deviceList, 20);
        List<OptDeviceMonitorAnalyseData> saveList = new ArrayList<>();
        splitList.parallelStream().forEach(list -> {
            // 创建连接
            OpenTSDBClient queryClient = null;
            try {
                queryClient = openTSDBUtils.readClient();
                OpenTSDBClient finalQueryClient = queryClient;
//                    String[] deviceCodes = list.stream().map(OptDevice::getDeviceCode).toArray(String[]::new);
                // 30个分一组 进行查询
                List<List<OptDevice>> split = CollectionUtil.split(list, 30);
                for (List<OptDevice> optDevices : split) {
                    optDevices.parallelStream().forEach(optDevice -> {
                        try {
                            double value = iotService.avgBySnAndCode( optDevice.getDeviceCode(), targetMonitorInfo.getCode(),  startTime,  endTime);
                            // 处理一下液位高度的容错 统一改为m
                            if (value > 7 && Constant.MonitorInfo.M_0x05D1.getCode().equals(targetMonitorInfo.getCode())) {
                                value = NumberUtil.div(value, 100D, 3);
                            }
                            saveList.add(createAnalyseData(optDevice, monitorInfo, value, startTime));
                        } catch (Exception e) {
                            log.error("{} ~ {}: 设备:{}, {}查询失败", startTime, endTime, optDevice.getDeviceCode(), monitorInfo.getName(), e);
                        }
                    });
                }
            } catch (IOReactorException e) {
                log.error("{} ~ {}: {}查询, 创建opentsdb连接失败", startTime, endTime, monitorInfo.getName(), e);
            } finally {
                openTSDBUtils.closeClient(queryClient);
            }
        });
        if (CollectionUtil.isNotEmpty(saveList)) {
            saveBatch(saveList);
        }
        log.info("{} ~ {}: {}聚合内容统计结束, 耗时:{}", startTime, endTime, monitorInfo.getName(), (System.currentTimeMillis() - start));
        return new AsyncResult<>(true);
    }

    /**
     * 获取统计分析的原有监测指标
     * @param monitorInfo 统计分析的监测指标
     * @return 分析的监测指标
     */
    public Constant.MonitorInfo getTargetMonitorInfo(Constant.MonitorInfo monitorInfo) {
        if (Constant.MonitorInfo.C_CC0001.equals(monitorInfo)) {
            return Constant.MonitorInfo.M_0x0590;
        } else if (Constant.MonitorInfo.C_CC0002.equals(monitorInfo)) {
            return Constant.MonitorInfo.M_0x0527;
        } else if (Constant.MonitorInfo.C_CC0003.equals(monitorInfo)) {
            return Constant.MonitorInfo.M_0x0528;
        } else if (Constant.MonitorInfo.C_CC0006.equals(monitorInfo)) {
            return Constant.MonitorInfo.M_0x0523;
        } else if (Constant.MonitorInfo.C_CC0007.equals(monitorInfo)) {
            return Constant.MonitorInfo.M_0x05D1;
        } else if (Constant.MonitorInfo.C_CC0008.equals(monitorInfo)) {
            return Constant.MonitorInfo.M_0x0566;
        } else {
            return null;
        }
    }

    /**
     * 计算日均
     */
    public void analyseRiJun(Date analyseDate) {
        List<OptDeviceDto> optDeviceDtos = iOptDeviceService.selectPumpStationDeviceList(null);
        Map<Long, List<OptDeviceDto>> pumpStationGroup = optDeviceDtos.stream().collect(Collectors.groupingBy(OptDeviceDto::getPumpStationId));
        for (Map.Entry<Long, List<OptDeviceDto>> entry : pumpStationGroup.entrySet()) {
            if (CollectionUtil.isEmpty(entry.getValue())) {
                log.error("泵站编码: {}, 不含有任何设备", entry.getKey());
                continue;
            }
            OptDeviceDto codAdDevice = null;
                    /*CollectionUtil.findOne(entry.getValue(), optDeviceDto ->
                    Constant.EquipmentType.SR500_L_Y0_SNY.getCode().equals(optDeviceDto.getDeviceType())
            );*/
            OptDeviceDto llDevice = null; /*CollectionUtil.findOne(entry.getValue(), optDeviceDto ->
                    Constant.EquipmentType.SR500_L_Y0_SNY.getCode().equals(optDeviceDto.getDeviceType())
            );*/
            if (codAdDevice == null) {
                log.error("泵站编码: {}, 不含有COD+氨氮设备", entry.getKey());
                continue;
            } else if (llDevice == null) {
                log.error("泵站编码: {}, 不含有流量设备", entry.getKey());
                continue;
            }
            // cod+氨氮类型设备编码
            String codAdCode = codAdDevice.getDeviceCode();
            // 流量类型设备编码
            String llCode = llDevice.getDeviceCode();
            // 昨天的日期
            String yesterday = DateUtil.formatDate(DateUtil.offsetDay(analyseDate, -1));
            // 查昨日累计流量
            LambdaQueryWrapper<OptDeviceMonitorAnalyseData> llWrapper = Wrappers.<OptDeviceMonitorAnalyseData>lambdaQuery()
                    .eq(OptDeviceMonitorAnalyseData::getDeviceCode, llCode)
                    .eq(OptDeviceMonitorAnalyseData::getCode, Constant.MonitorInfo.C_CC0001.getCode())
                    .eq(OptDeviceMonitorAnalyseData::getMonitorTime, yesterday)
                    .orderByDesc(OptDeviceMonitorAnalyseData::getMonitorTime)
                    .last("LIMIT 1");
            OptDeviceMonitorAnalyseData llOne = getOne(llWrapper);
            if (llOne == null) {
                log.error("昨日流量为空");
                return;
            }
            // 查昨日平均cod
            LambdaQueryWrapper<OptDeviceMonitorAnalyseData> codWrapper = Wrappers.<OptDeviceMonitorAnalyseData>lambdaQuery()
                    .eq(OptDeviceMonitorAnalyseData::getDeviceCode, codAdCode)
                    .eq(OptDeviceMonitorAnalyseData::getCode, Constant.MonitorInfo.C_CC0002.getCode())
                    .eq(OptDeviceMonitorAnalyseData::getMonitorTime, yesterday)
                    .orderByDesc(OptDeviceMonitorAnalyseData::getMonitorTime)
                    .last("LIMIT 1");
            OptDeviceMonitorAnalyseData codOne = getOne(codWrapper);
            if (codOne == null) {
                log.error("昨日COD为空");
                return;
            }

            // COD排放量
            double codPfl = NumberUtil.div(NumberUtil.mul(llOne.getCodeValue(), codOne.getCodeValue()), 1000, 3);
            OptDeviceMonitorAnalyseData analyseData = new OptDeviceMonitorAnalyseData();
            analyseData.setId(null);
            analyseData.setDeviceName(codAdDevice.getDeviceName());
            analyseData.setDeviceCode(codAdDevice.getDeviceCode());
            analyseData.setSiteName(codAdDevice.getSiteName());
            analyseData.setDeviceType(codAdDevice.getDeviceType());
            analyseData.setInstallTime(codAdDevice.getInstallTime());
            analyseData.setAbx(codAdDevice.getAbx());
            analyseData.setAby(codAdDevice.getAby());
            analyseData.setCode(Constant.MonitorInfo.C_CC0004.getCode());
            analyseData.setCodeValue(codPfl);
            analyseData.setDataUnit(Constant.MonitorInfo.C_CC0004.getUnit());
            analyseData.setMonitorTime(DateUtil.parseDate(yesterday));
            analyseData.setMonitorName(Constant.MonitorInfo.C_CC0004.getName());
            save(analyseData);

            // 查昨日平均氨氮
            LambdaQueryWrapper<OptDeviceMonitorAnalyseData> adWrapper = Wrappers.<OptDeviceMonitorAnalyseData>lambdaQuery()
                    .eq(OptDeviceMonitorAnalyseData::getDeviceCode, codAdCode)
                    .eq(OptDeviceMonitorAnalyseData::getCode, Constant.MonitorInfo.C_CC0003.getCode())
                    .eq(OptDeviceMonitorAnalyseData::getMonitorTime, yesterday)
                    .orderByDesc(OptDeviceMonitorAnalyseData::getMonitorTime)
                    .last("LIMIT 1");
            OptDeviceMonitorAnalyseData adOne = getOne(adWrapper);
            if (adOne == null) {
                throw new ServiceException("前日氨氮为空");
            }

            // 氨氮排放量
            double adPfl = NumberUtil.div(NumberUtil.mul(llOne.getCodeValue(), adOne.getCodeValue()), 1000, 3);
            OptDeviceMonitorAnalyseData analyseData1 = new OptDeviceMonitorAnalyseData();
            analyseData1.setId(null);
            analyseData1.setDeviceName(codAdDevice.getDeviceName());
            analyseData1.setDeviceCode(codAdDevice.getDeviceCode());
            analyseData1.setSiteName(codAdDevice.getSiteName());
            analyseData1.setDeviceType(codAdDevice.getDeviceType());
            analyseData1.setInstallTime(codAdDevice.getInstallTime());
            analyseData1.setAbx(codAdDevice.getAbx());
            analyseData1.setAby(codAdDevice.getAby());
            analyseData1.setCode(Constant.MonitorInfo.C_CC0005.getCode());
            analyseData1.setCodeValue(adPfl);
            analyseData1.setDataUnit(Constant.MonitorInfo.C_CC0005.getUnit());
            analyseData1.setMonitorTime(DateUtil.parseDate(yesterday));
            analyseData1.setMonitorName(Constant.MonitorInfo.C_CC0005.getName());
            save(analyseData1);
        }
    }

    public OptDeviceMonitorAnalyseData createAnalyseData(OptDevice optDevice, Constant.MonitorInfo monitorInfo, Double value, Date time) {
        OptDeviceMonitorAnalyseData analyseData = new OptDeviceMonitorAnalyseData();
        analyseData.setId(null);
        analyseData.setDeviceName(optDevice.getDeviceName());
        analyseData.setDeviceCode(optDevice.getDeviceCode());
        analyseData.setSiteName(optDevice.getSiteName());
        analyseData.setDeviceType(optDevice.getDeviceType());
        analyseData.setInstallTime(optDevice.getInstallTime());
        analyseData.setAbx(optDevice.getAbx());
        analyseData.setAby(optDevice.getAby());
        analyseData.setCode(monitorInfo.getCode());
        analyseData.setCodeValue(value);
        analyseData.setDataUnit(monitorInfo.getUnit());
        analyseData.setMonitorTime(time);
        analyseData.setMonitorName(monitorInfo.getName());
        return analyseData;
    }
}
